package org.dtrd.modules.service.controller;


import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.dtrd.base.BaseController;
import org.dtrd.common.api.vo.Result;
import org.dtrd.common.aspect.annotation.AutoLog;
import org.dtrd.common.system.util.JwtUtil;
import org.dtrd.common.util.DateUtils;
import org.dtrd.config.system.Constant.PackageServiceStatus;
import org.dtrd.modules.base.service.BaseCommonService;
import org.dtrd.modules.content.tags.service.IDtrdExtEmsYwTagsService;
import org.dtrd.modules.doctor.service.IDtrdEntRdDoctorService;
import org.dtrd.modules.service.entity.bean.*;
import org.dtrd.modules.service.entity.po.DtrdRlPackagePatient;
import org.dtrd.modules.service.entity.request.*;
import org.dtrd.modules.service.service.IDtrdEntRdServicePackageService;
import org.dtrd.modules.service.service.IDtrdRlPackagePatientService;
import org.dtrd.modules.service.service.IDtrdRlPatientServiceDetailService;
import org.dtrd.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static org.dtrd.common.constant.CommonConstant.*;
import static org.dtrd.config.system.SystemState.ResponseState.*;

/**
 * <p>
 * 患者和服务包关系表 前端控制器
 * </p>
 *
 * @author QR
 * @since 2021-12-16
 */
@Api(tags = "服务套餐")
@RestController
@RequestMapping("/107/03/")
@Slf4j
public class PatientPackageController extends BaseController {

    @Autowired
    private IDtrdRlPackagePatientService packagePatientService;
    @Autowired
    private IDtrdRlPatientServiceDetailService patientServiceDetailRlService;
    @Autowired
    private IDtrdEntRdServicePackageService packageService;
    @Autowired
    private IDtrdEntRdDoctorService doctorService;
    @Autowired
    private BaseCommonService baseCommonService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IDtrdExtEmsYwTagsService tagsService;

    @ApiOperation("分页获取患者服务列表")
    @PostMapping("1070314")
    public Result<?> getPatientServiceList(@RequestBody PatientPackageListRequest request) {
        Integer patientId = request.getPatientId();
        if (isIntParamInvalid(patientId)) {
            return error(STATE_PARAMS_MISSING);
        }
        Integer page = getIntParam(request.getPage(), 1);
        Integer pageSize = getPageSize(request.getPageSize(), 20);
        String orgCode = request.getOrgCode();
        Integer status = request.getStatus();
        IPage<PatientPackageListInfo> list = packagePatientService.pagePatientPackage(patientId, page, pageSize, orgCode, status);
        String logContent = String.format("分页获取患者服务列表, 患者id: %d", patientId);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return Result.OK(list);
    }

    @ApiOperation("查询患者的服务详情")
    @PostMapping("1070315")
    public Result<?> getPatientServiceDetail(@RequestBody PatientServiceDetailRequest request) {
        Integer relationId = request.getPackageId();

        Integer patientId = request.getPatientId();
        if (isIntParamInvalid(relationId) || isIntParamInvalid(patientId)) {
            return error(STATE_PARAMS_MISSING);
        }
        Map<PatientServiceItemKey, List<ServiceDetailItem>> periodToServiceDetail = patientServiceDetailRlService.getPatientServiceDetail(patientId, relationId);
        if (MapUtil.isEmpty(periodToServiceDetail)) {
            return error(STATE_NO_RECORD);
        }
        JSONObject result = new JSONObject();
        PatientServiceRelationInfo patientServiceRlInfo = packageService.getPatientServiceRelationInfo(patientId, relationId);
        result.put("basicInfo", patientServiceRlInfo);
        result.put("totalServiceItems", convertMapToList(periodToServiceDetail));
        result.put("defaultPeriod", patientServiceDetailRlService.getPatientPackageSchedule(patientId, relationId));
        String logContent = String.format("查询患者的服务详情, 患者id: %d, 服务包id: %d", patientId, relationId);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return MapUtil.isEmpty(periodToServiceDetail) ? error(STATE_NO_RECORD) : Result.OK(result);
    }

    // deprecated  肖 2022-07-01 21:13:28
//    @ApiOperation("新增患者和服务包关系")
//    @PostMapping("1070316")
//    public Result<?> saveOrUpdatePackagePatient(@RequestBody PackagePatientRelation dto) {
//        Integer patientId = dto.getPatientId();
//        Integer packageId = dto.getPackageId();
//        Date startTime = dto.getStartTime();
//        Date endTime = dto.getEndTime();
//        if (isIntParamInvalid(packageId) || isIntParamInvalid(packageId)) {
//            return error(STATE_PARAMS_MISSING);
//        }
//        // 新增服务中服务包检测  开始时间小于今天 即服务中服务包  肖 2022-06-30 18:20:26
//        if (DateUtils.isPast(startTime)) {
//            // 已开始服务包
//            DtrdRlPackagePatient patientPackage = packagePatientService.getServicingPatientPackage(patientId);
//            if (patientPackage != null) {
//                log.info("DtrdEntRdArchiveReverseSchemeServiceImpl.saveReverseScheme.[dto] 已存在服务中服务包");
//                return Result.error(STATE_OPERATION_FAILURE.getCode(), "已存在服务中服务包");
//            }
//        }
//        packagePatientService.savePatientPackageRelation(patientId, packageId, servicePackage.getPeriodUnit(), startTime, endTime);
//        String logContent = String.format("新增或修改患者和服务包关系表, 患者id: %d, 服务包id: %d", patientId, packageId);
//        baseCommonService.addLog(logContent, OPERATE_TYPE_SAVE_OR_UPDATE);
//        return Result.OK();
//    }

    @ApiOperation("删除患者和服务包关系")
    @DeleteMapping("1070317")
    @AutoLog(value = "删除患者和服务包关系", operateType = OPERATE_TYPE_DELETE)
    public Result<?> removePackagePatient(@RequestParam Integer id) {
        if (isIntParamInvalid(id)) {
            return error(STATE_PARAMS_MISSING);
        }
        boolean result = packagePatientService.removePackagePatient(id);
        String logContent = String.format("删除患者和服务包关系表, 删除id: %d", id);
        baseCommonService.addLog(logContent, OPERATE_TYPE_DELETE);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation(value = "设置服务项的状态", notes = "type 1: 已完成, 0: 未完成")
    @PostMapping("1070318")
    public Result<?> getChangeServiceItemStatus(@RequestBody ServiceItemStatusRequest request, HttpServletRequest httpServletRequest) {
        Integer serviceItemId = request.getServiceItemId();
        Integer type = request.getType();
        // 空参校验
        if (serviceItemId == null || type == null) {
            return error(STATE_PARAMS_MISSING);
        }
        // 校验设置的type
        if (Boolean.FALSE.equals(patientServiceDetailRlService.checkServiceItemType(type))) {
            return error(STATE_PARAMS_ERROR);
        }
        String username=null;
        // 判断执行人身份
        username = JwtUtil.getUserNameByToken(httpServletRequest);
        if (username == null && request.getDoctorId() != null) {
            username = doctorService.getDoctorName(request.getDoctorId());
        }
        boolean result = packagePatientService.updateServiceItemState(serviceItemId, request.getRemark(), type, username);
        log.info("设置服务项状态, 服务项id: {}, 操作人: {}", serviceItemId, username);
        String logContent = String.format("设置服务项的状态, 设置id: %d, 设置类型：%d", serviceItemId, type);
        baseCommonService.addLog(logContent, OPERATE_TYPE_UPDATE);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation(value = "结束服务包")
    @PostMapping("1070319")
    public Result<?> finishServicePack(@RequestBody @Validated FinishServicePackRequest request, HttpServletRequest httpServletRequest) {
        // 判断执行人身份
        String username = JwtUtil.getUserNameByToken(httpServletRequest);
        if (!ObjectUtils.nullSafeEquals(username, request.getExecutorName())) {
            log.info("PatientPackageController.finishServicePack.[request, httpServletRequest] executor is not the login user");
//            return error(STATE_REQUEST_FAILURE);
        }
        DtrdRlPackagePatient po = packagePatientService.getById(request.getServicePackageId());
        if (po == null) {
            return error(STATE_PARAMS_ERROR);
        }
        if (!PackageServiceStatus.isQuitAble(po.getStatus())) {
            // 仅限已到期和进行中可以结束
            return error(STATE_OPERATION_FAILURE);
        }
        boolean result = packagePatientService.finishedServicePackage(po, request.getServicePackageId(), request.getExecutorId(), request.getExecutorName(), request.getServiceEffect(), request.getServiceEndDesc());
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation("保存患者服务评价")
    @PostMapping("1070320")
    public Result<?> savePatientEvaluation(@RequestBody PatientEvaluationRequest request) {
        Integer itemId = request.getServiceItemId();
        Integer evaluation = request.getEvaluation();
        List<Integer> tagIds = request.getTagIds();
        if (itemId == null || evaluation == null) {
            return error(STATE_PARAMS_MISSING);
        }
        boolean result = patientServiceDetailRlService.savePatientEvaluation(itemId, evaluation, tagIds);
        String logContent = String.format("患者评价服务: %d, 等级: %d", itemId, evaluation);
        baseCommonService.addLog(logContent, OPERATE_TYPE_UPDATE);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation("手动添加服务项")
    @PostMapping("1070321")
    @AutoLog(value = "手动添加服务项", operateType = OPERATE_TYPE_ADD)
    public Result<?> addPatientPackageService(@RequestBody PatientServiceRequest request, HttpServletRequest httpServletRequest) {
        log.info("PatientServiceDetail: =====" + request);
        String username=null;
        // 判断执行人身份
        username = JwtUtil.getUserNameByToken(httpServletRequest);
        if (username == null) {
            username = doctorService.getDoctorName(request.getDoctorId());
        }
        boolean result = patientServiceDetailRlService.saveOrUpdatePatientServiceDetail(request, username);
        String logContent = String.format("添加新的服务项: %s", request);
        baseCommonService.addLog(logContent, OPERATE_TYPE_ADD);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation("删除添加的服务项")
    @DeleteMapping("1070322")
    @AutoLog(value = "删除添加的服务项", operateType = OPERATE_TYPE_DELETE)
    public Result<?> deletePatientPackageService(@RequestParam Integer id) {

        boolean result = patientServiceDetailRlService.removePatientServiceDetail(id);
        String logContent = String.format("删除添加的服务项: %s", id);
        baseCommonService.addLog(logContent, OPERATE_TYPE_ADD);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    private List<JSONObject> convertMapToList(Map<PatientServiceItemKey, List<ServiceDetailItem>> map) {
        ArrayList<JSONObject> arrayList = new ArrayList<>(map.size());
        for (Map.Entry<PatientServiceItemKey, List<ServiceDetailItem>> entry : map.entrySet()) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("time", entry.getKey());
            jsonObject.put("serviceItems", entry.getValue());
            arrayList.add(jsonObject);
        }
        return arrayList;
    }
}
